package org.hiro.actions;

import com.intellij.codeInsight.generation.PsiElementClassMember;
import static com.intellij.openapi.application.ApplicationManager.getApplication;
import com.intellij.openapi.project.Project;
import static com.intellij.openapi.ui.Messages.getWarningIcon;
import static com.intellij.openapi.ui.Messages.showMessageDialog;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.codeStyle.CodeStyleManager;
import org.hiro.CodeGenerationException;
import static org.hiro.GenerateBuilderContext.getConfiguration;
import static org.hiro.psi.GeneratedBuilderHelper.WITH_METHOD_BASIC_TEMPLATE;
import static org.hiro.psi.GeneratedBuilderHelper.getWithMethodText;

import java.util.List;

class GenerateWithMethodWriter implements Runnable {

    private final List<PsiElementClassMember> fields;
    private final Project project;
    private final CodeStyleManager codeStyleManager;
    private final PsiElementFactory elementFactory;
    private final PsiClass currentClass;

    private String firstMethodName;

    public GenerateWithMethodWriter(Project project, PsiClass currentClass, PsiElementFactory elementFactory, CodeStyleManager codeStyleManager, List<PsiElementClassMember> fields) {
        this.project = project;
        this.currentClass = currentClass;
        this.elementFactory = elementFactory;
        this.codeStyleManager = codeStyleManager;
        this.fields = fields;
    }

    public void run() {
        getApplication().runWriteAction(new Runnable() {
            public void run() {
                try {
                    for (PsiElementClassMember selectedField : fields) {
                        PsiMethod newMethod = elementFactory.createMethodFromText(getWithMethodText(selectedField, currentClass.getName(), WITH_METHOD_BASIC_TEMPLATE), null);
                        codeStyleManager.reformat(newMethod);


                        getConfiguration().getInsertionPolicy().insertNewMethod(currentClass, newMethod);

                        if (firstMethodName==null) {
                            firstMethodName = newMethod.getName();
                        }
                    }
                } catch (CodeGenerationException e) {
                    showMessageDialog(project, "Velocity error generating code - see IDEA log for more details:\n" + e.getMessage(), "Warning", getWarningIcon());
                }
            }
        });
    }

    public String getFirstMethodName() {
        return firstMethodName;
    }
}